package com.app;

import java.security.spec.KeySpec;

import javax.crypto.Cipher;
import javax.crypto.SecretKey;
import javax.crypto.SecretKeyFactory;
import javax.crypto.spec.DESKeySpec;

import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;


/**
 * Encrypter
 */
public class CrypticService {
	
	public static final String DES_ENCRYPTION_SCHEME = "DES";
	public static final String DEFAULT_ENCRYPTION_KEY = "The key is funfusion";
	public static final String UNICODE_FORMAT = "UTF8";
	
	private KeySpec	keySpec;
	private SecretKeyFactory keyFactory;
	private Cipher cipher;
	
	/**
	 * @param encryptionScheme
	 */
	public CrypticService() {
		this(DES_ENCRYPTION_SCHEME, DEFAULT_ENCRYPTION_KEY);
	}

	/**
	 * @param encryptionScheme
	 * @param encryptionKey
	 */
	private CrypticService(String encryptionScheme, String encryptionKey) {
		byte[] keyAsBytes;
		try {
			keyAsBytes = encryptionKey.getBytes(UNICODE_FORMAT);
			keySpec = new DESKeySpec(keyAsBytes);
			keyFactory = SecretKeyFactory.getInstance(encryptionScheme);
			cipher = Cipher.getInstance(encryptionScheme);
		}
		catch (Exception excp) {
			excp.printStackTrace();
		}
	}
	
	public String encrypt(String plainString) {
		if (plainString == null || plainString.trim().length() == 0)
			throw new IllegalArgumentException("The input string is null or empty");

		try {
			SecretKey key = keyFactory.generateSecret(keySpec);
			cipher.init(Cipher.ENCRYPT_MODE, key);
			byte[] cleartext = plainString.getBytes(UNICODE_FORMAT);
			byte[] ciphertext = cipher.doFinal(cleartext);
			BASE64Encoder base64encoder = new BASE64Encoder();
			return base64encoder.encode(ciphertext);
		}
		catch (Exception excp) {
			excp.printStackTrace();
		}
		return new String("");
	}

	public String decrypt(String encryptedString) {
		if (encryptedString == null || encryptedString.trim().length() <= 0)
			throw new IllegalArgumentException("encrypted string was null or empty");
		
		try {
			SecretKey key = keyFactory.generateSecret(keySpec);
			cipher.init(Cipher.DECRYPT_MODE, key);
			BASE64Decoder base64decoder = new BASE64Decoder();
			byte[] cleartext = base64decoder.decodeBuffer(encryptedString);
			byte[] ciphertext = cipher.doFinal(cleartext);
			return bytes2String(ciphertext);
		}
		catch (Exception excp) {
			excp.printStackTrace();
		}
		return new String("");
	}
	
	private static String bytes2String(byte[] bytes) {
		StringBuffer stringBuffer = new StringBuffer();
		for (int i = 0; i < bytes.length; i++) {
			stringBuffer.append((char) bytes[i]);
		}
		return stringBuffer.toString();
	}
	/*
	public static void main(String args[]) {
		CrypticService crypticService = new CrypticService();
		String string = new String("TESTSTring");
		String encryptedString = crypticService.encrypt(string);
		String decryptedString = crypticService.decrypt(encryptedString);
		System.out.println("Encrypted String is "+ encryptedString);
		System.out.println("Decrypted String is "+ decryptedString );
	}*/
}
